import {
  InfoCircleOutlined,
  SearchOutlined,
  SyncOutlined,
  QuestionCircleOutlined,
  ReloadOutlined,
} from '@ant-design/icons'
import { keywordCompare } from '@gnlab/utils'
import { Tooltip, App, Spin, Button, Input, Card } from 'antd'
import throttle from 'lodash/throttle'
import { Empty, AvatarImage } from '@/desktop/components'
import { useScanStatus } from '@/desktop/logics/container'
import { colors, breakWord, flexCenter, fullAbsolute } from '@/desktop/styles'
import { useStreams } from '@/lib/utils'
import services from '@/services'
import { getFormattedQywxs, type AccountQywx, AccountQywxStatus } from '@/services/qywxs'

export function HistoryAddQywx() {
  const [account] = useStreams(services.auth.account$)
  const { message } = App.useApp()

  const [allQywxs, setAllQywxs] = useState<AccountQywx[] | null>(null)
  const [loading, setLoading] = useState(false)
  const load = useCallback(async () => {
    setLoading(true)
    const res = await getFormattedQywxs(account?.id ?? '', false)
    setLoading(false)
    if (res.success) {
      const qywxs = res.data.filter(qywx => qywx.status !== AccountQywxStatus.Online)
      setAllQywxs(qywxs)
    } else {
      void message.warning('企微列表加载失败：' + res.error)
    }
  }, [message, account])
  useEffect(() => {
    void load()
    const intervalId = setInterval(async () => load(), 15 * 1000)
    return () => clearInterval(intervalId)
  }, [load])

  const [keyword, setKeyword] = useState('')
  const keywordOnChange = useMemo(() => throttle(setKeyword, 100), [])
  const qywxs = useMemo(() => {
    if (!keyword) return allQywxs ?? []
    return (allQywxs ?? []).filter(
      qywx =>
        keywordCompare(keyword, qywx.friendlyName) ||
        qywx.wxid.includes(keyword) ||
        qywx.hostname.includes(keyword),
    )
  }, [allQywxs, keyword])

  return <Spin delay={500} spinning={!allQywxs}>
    <header css={s.header}>
      <Input
        className="search"
        prefix={<SearchOutlined />}
        placeholder="搜索企微号"
        value={keyword}
        onChange={e => keywordOnChange(e.target.value)}
      />
      <Button type="link" icon={<SyncOutlined />} loading={loading} onClick={load}>
        刷新
      </Button>
      <Tooltip title="如有找不到的企微，请与管理员确认是否登到了其他账号。">
        <QuestionCircleOutlined css={s.notFoundTips} />
      </Tooltip>
    </header>

    {allQywxs && !qywxs.length ? (
      <Empty css={{ marginTop: 100 }} description="没有符合条件的企微" />
    ) : null}

    <div css={s.list}>{qywxs.map(qywx => <QywxItem key={qywx.wxid} qywx={qywx} />)}</div>
  </Spin>
}

enum Status {
  待登录 = 0,
  登录中 = 1,
  需扫码 = 2,
  刷新二维码 = 3, // 其实和“登录中”是一个状态，只不过是因为点击“刷新二维码”而触发
  登录失败 = 4,
  已登录 = 5,
}

function QywxItem({ qywx }: { qywx: AccountQywx }) {
  const [status, setStatus] = useState(Status.待登录)
  const [qrcode, setQrcode] = useState('')

  const login = useCallback(
    async function (forRefreshQrcode = false) {
      setStatus(forRefreshQrcode ? Status.刷新二维码 : Status.登录中)
          const res = await services.qywxs.containerLogin(qywx.hostname, forRefreshQrcode)
      if (res.success) {
        const { Status: status, QrCode: qrcode } = res.data
        if (status === 0) setStatus(Status.已登录)
        else if (status === 4 && qrcode) {
          setStatus(Status.需扫码)
          setQrcode(qrcode)
        } else {
          setStatus(Status.登录失败)
        }
      } else {
        setStatus(Status.登录失败)
      }
    },
    [qywx.hostname],
  )

  const { scaned } = useScanStatus(qywx.hostname, login)

  let action: React.ReactNode
  if (status === Status.待登录) {
    action = <div css={s.action} key="login" onClick={async () => login()}>
      登录
    </div>
  } else if (status === Status.登录中) {
    action = <div css={s.action} key="login">
      登录中...
    </div>
  } else if (status === Status.需扫码) {
    action = <Tooltip
      mouseEnterDelay={0}
      color="#fff"
      title={
        <div css={s.scan}>
          <header>请用企微扫码登录</header>
          <div css={s.qrcode}>
            <img src={qrcode} />
            {scaned ? <div className="scaned">已扫码</div> : null}
          </div>
          <Button type="link" icon={<ReloadOutlined />} onClick={async () => login(true)}>
            刷新二维码
          </Button>
        </div>
      }
    >
      <div css={s.action} className="need-scan" key="login">
        <InfoCircleOutlined />
        <span>需扫码登录</span>
      </div>
    </Tooltip>
  } else if (status === Status.刷新二维码) {
    action = <div css={s.action} key="login">
      刷新中...
    </div>
  } else if (status === Status.登录失败)
    action = <Tooltip title="登录失败，请联系平台技术支持">
      <div css={s.action} className="failed" key="login">
        <InfoCircleOutlined />
        <span>登录失败</span>
      </div>
    </Tooltip>
  else {
    action = <div css={s.action} className="success" key="login">
      登录成功
    </div>
  }

  return <Card css={s.qywx} bordered={false} actions={[action]}>
    <Card.Meta
      avatar={<AvatarImage size={64} src={qywx.avatar} />}
      title={qywx.friendlyName}
      description={
        <>
          <div>
            <label>公司</label>
            <div>{qywx.corpname}</div>
          </div>
          <div>
            <label>wxid</label>
            <div>{qywx.wxid}</div>
          </div>
          <div>
            <label>hostname</label>
            <div>{qywx.hostname}</div>
          </div>
        </>
      }
    />
  </Card>
}

const s = {
  header: css`
    display: flex;
    white-space: nowrap;
    .search {
      width: 300px;
    }
  `,
  notFoundTips: css`
    color: ${colors.link};
    font-size: 16px;
  `,

  list: css`
    min-height: 300px;
    padding-top: 20px;
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    column-gap: 20px;
    row-gap: 20px;
  `,
  qywx: css`
    min-height: 185px;
    width: 300px;
    .ant-card-meta-title {
      ${breakWord};
      white-space: normal;
    }
    .ant-card-meta-description {
      font-size: 12px;
      & > div {
        display: flex;
        &:not(:last-child) {
          margin-bottom: 3px;
        }
        label {
          flex-shrink: 0;
        }
        label + div {
          ${breakWord};
          padding-left: 0.75em;
          color: #000;
        }
      }
    }
    .ant-card-actions li {
      margin: 0;
    }
  `,
  action: css`
    color: ${colors.link};
    padding: 12px 0;
    &:hover {
      opacity: 0.8;
    }
    &.need-scan,
    &.failed {
      ${flexCenter};
      color: ${colors.error};
      .anticon {
        font-size: 16px;
        margin-right: 0.5em;
      }
    }
    &.success {
      color: ${colors.success};
      cursor: default;
    }
  `,
  scan: css`
    text-align: center;
    header {
      color: #000;
      padding: 12px 0 4px;
    }
  `,

  qrcode: css`
    background-color: #fcfcfc;
    border-radius: 4px;
    height: 220px;
    margin: 0 auto;
    position: relative;
    width: 220px;
    img {
      display: block;
      height: 100%;
      width: 100%;
    }
    .scaned {
      ${flexCenter};
      ${fullAbsolute};
      background-color: rgba(255, 255, 255, 0.85);
      color: #222;
      font-size: 20px;
      letter-spacing: 1px;
    }
  `,
}
